{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to train and tune a random forest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:40.329600Z",
     "start_time": "2020-06-19T14:00:40.327285Z"
    }
   },
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:40.833570Z",
     "start_time": "2020-06-19T14:00:40.331231Z"
    }
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import os, sys\n",
    "import numpy as np\n",
    "\n",
    "from numpy.random import choice\n",
    "import pandas as pd\n",
    "from scipy.stats import spearmanr\n",
    "\n",
    "from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier\n",
    "from sklearn.model_selection import GridSearchCV, cross_val_score\n",
    "from sklearn.metrics import make_scorer\n",
    "import joblib\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:40.837101Z",
     "start_time": "2020-06-19T14:00:40.834624Z"
    }
   },
   "outputs": [],
   "source": [
    "sys.path.insert(1, os.path.join(sys.path[0], '..'))\n",
    "from utils import MultipleTimeSeriesCV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:40.855295Z",
     "start_time": "2020-06-19T14:00:40.837935Z"
    }
   },
   "outputs": [],
   "source": [
    "sns.set_style('white')\n",
    "np.random.seed(seed=42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "results_path = Path('results', 'random_forest')\n",
    "if not results_path.exists():\n",
    "    results_path.mkdir(parents=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:40.915698Z",
     "start_time": "2020-06-19T14:00:40.856137Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "MultiIndex: 56756 entries, ('A', Timestamp('2010-12-31 00:00:00')) to ('ZION', Timestamp('2017-11-30 00:00:00'))\n",
      "Data columns (total 27 columns):\n",
      " #   Column         Non-Null Count  Dtype  \n",
      "---  ------         --------------  -----  \n",
      " 0   atr            56756 non-null  float64\n",
      " 1   bb_down        56756 non-null  float64\n",
      " 2   bb_high        56756 non-null  float64\n",
      " 3   bb_low         56756 non-null  float64\n",
      " 4   bb_mid         56756 non-null  float64\n",
      " 5   bb_up          56756 non-null  float64\n",
      " 6   macd           56756 non-null  float64\n",
      " 7   natr           56756 non-null  float64\n",
      " 8   rsi            56756 non-null  float64\n",
      " 9   sector         56756 non-null  object \n",
      " 10  return_1m      56756 non-null  float64\n",
      " 11  return_3m      56756 non-null  float64\n",
      " 12  return_6m      56756 non-null  float64\n",
      " 13  return_12m     56756 non-null  float64\n",
      " 14  beta           56756 non-null  float64\n",
      " 15  SMB            56756 non-null  float64\n",
      " 16  HML            56756 non-null  float64\n",
      " 17  RMW            56756 non-null  float64\n",
      " 18  CMA            56756 non-null  float64\n",
      " 19  momentum_3     56756 non-null  float64\n",
      " 20  momentum_6     56756 non-null  float64\n",
      " 21  momentum_3_6   56756 non-null  float64\n",
      " 22  momentum_12    56756 non-null  float64\n",
      " 23  momentum_3_12  56756 non-null  float64\n",
      " 24  year           56756 non-null  int64  \n",
      " 25  month          56756 non-null  int64  \n",
      " 26  target         56756 non-null  float64\n",
      "dtypes: float64(24), int64(2), object(1)\n",
      "memory usage: 12.0+ MB\n"
     ]
    }
   ],
   "source": [
    "with pd.HDFStore('data.h5') as store:\n",
    "    data =store['us/equities/monthly']\n",
    "data.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:40.941093Z",
     "start_time": "2020-06-19T14:00:40.916848Z"
    }
   },
   "outputs": [],
   "source": [
    "y = data.target\n",
    "y_binary = (y > 0).astype(int)\n",
    "X = pd.get_dummies(data.drop('target', axis=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Random Forests"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Cross-validation parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:40.945574Z",
     "start_time": "2020-06-19T14:00:40.943089Z"
    }
   },
   "outputs": [],
   "source": [
    "n_splits = 10\n",
    "train_period_length = 60\n",
    "test_period_length = 6\n",
    "lookahead = 1\n",
    "\n",
    "cv = MultipleTimeSeriesCV(n_splits=n_splits,\n",
    "                          train_period_length=train_period_length,\n",
    "                          test_period_length=test_period_length,\n",
    "                          lookahead=lookahead)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:40.955909Z",
     "start_time": "2020-06-19T14:00:40.946845Z"
    }
   },
   "outputs": [],
   "source": [
    "rf_clf = RandomForestClassifier(n_estimators=100,             # default changed from 10 to 100 in version 0.22 \n",
    "                                criterion='gini', \n",
    "                                max_depth=None, \n",
    "                                min_samples_split=2, \n",
    "                                min_samples_leaf=1, \n",
    "                                min_weight_fraction_leaf=0.0, \n",
    "                                max_features='auto',\n",
    "                                max_leaf_nodes=None, \n",
    "                                min_impurity_decrease=0.0, \n",
    "                                min_impurity_split=None, \n",
    "                                bootstrap=True, \n",
    "                                oob_score=True, \n",
    "                                n_jobs=-1,\n",
    "                                random_state=42, \n",
    "                                verbose=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Cross-Validation with default settings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:58.268926Z",
     "start_time": "2020-06-19T14:00:40.956778Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.\n",
      "[Parallel(n_jobs=-1)]: Done   6 out of  10 | elapsed:   14.0s remaining:    9.3s\n",
      "[Parallel(n_jobs=-1)]: Done  10 out of  10 | elapsed:   17.2s finished\n"
     ]
    }
   ],
   "source": [
    "cv_score = cross_val_score(estimator=rf_clf,\n",
    "                           X=X,\n",
    "                           y=y_binary,\n",
    "                           scoring='roc_auc',\n",
    "                           cv=cv,\n",
    "                           n_jobs=-1,\n",
    "                           verbose=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:58.273631Z",
     "start_time": "2020-06-19T14:00:58.270041Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5236329094014294"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(cv_score)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Regression RF"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:58.290758Z",
     "start_time": "2020-06-19T14:00:58.274764Z"
    }
   },
   "outputs": [],
   "source": [
    "def rank_correl(y, y_pred):\n",
    "    return spearmanr(y, y_pred)[0]\n",
    "\n",
    "ic = make_scorer(rank_correl)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:00:58.304894Z",
     "start_time": "2020-06-19T14:00:58.292164Z"
    }
   },
   "outputs": [],
   "source": [
    "rf_reg = RandomForestRegressor(n_estimators=100, \n",
    "                                max_depth=None, \n",
    "                                min_samples_split=2, \n",
    "                                min_samples_leaf=1, \n",
    "                                min_weight_fraction_leaf=0.0, \n",
    "                                max_features='auto', \n",
    "                                max_leaf_nodes=None, \n",
    "                                min_impurity_decrease=0.0, \n",
    "                                min_impurity_split=None, \n",
    "                                bootstrap=True, \n",
    "                                oob_score=False, \n",
    "                                n_jobs=-1, \n",
    "                                random_state=None, \n",
    "                                verbose=0, \n",
    "                                warm_start=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:02:34.189925Z",
     "start_time": "2020-06-19T14:00:58.305894Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.\n",
      "[Parallel(n_jobs=-1)]: Done   6 out of  10 | elapsed:  1.3min remaining:   52.7s\n",
      "[Parallel(n_jobs=-1)]: Done  10 out of  10 | elapsed:  1.6min finished\n"
     ]
    }
   ],
   "source": [
    "cv_score = cross_val_score(estimator=rf_reg,\n",
    "                           X=X,\n",
    "                           y=y,\n",
    "                           scoring=ic,\n",
    "                           cv=cv,\n",
    "                           n_jobs=-1,\n",
    "                           verbose=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:02:34.193492Z",
     "start_time": "2020-06-19T14:02:34.190886Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.019866006883088493"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(cv_score)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Parameter Tuning"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The key configuration parameters include the various hyperparameters for the individual decision trees introduced in the notebook [decision_trees](01_decision_trees.ipynb). \n",
    "\n",
    "The following tables lists additional options for the two `RandomForest` classes:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "| Keyword      | Default | Description                                                                                                                |\n",
    "|--------------|---------|----------------------------------------------------------------------------------------------------------------------------|\n",
    "| bootstrap    | True    | Bootstrap samples during training                                                                                          |\n",
    "| n_estimators | 10      | # trees in the forest.                                                                                                     |\n",
    "| oob_score    | False   | Use out-of-bag samples to estimate the R2 on unseen data                                                                   |\n",
    "| warm_start   | False   | Reuse result of previous call to continue training and add more trees to the ensemble, otherwise, train a whole new forest |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- The `bootstrap` parameter activates in the preceding bagging algorithm outline, which in turn enables the computation of the out-of-bag score (oob_score) that estimates the generalization accuracy using samples not included in the bootstrap sample used to train a given tree (see next section for detail). \n",
    "- The `n_estimators` parameter defines the number of trees to be grown as part of the forest. Larger forests perform better, but also take more time to build. It is important to monitor the cross-validation error as a function of the number of base learners to identify when the marginal reduction of the prediction error declines and the cost of additional training begins to outweigh the benefits.\n",
    "- The `max_features` parameter controls the size of the randomly selected feature subsets available when learning a new decision rule and split a node. A lower value reduces the correlation of the trees and, thus, the ensemble's variance, but may also increase the bias. Good starting values are `n_features` (the number of training features) for regression problems and `sqrt(n_features)` for classification problems, but will depend on the relationships among features and should be optimized using cross-validation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Random forests are designed to contain deep fully-grown trees, which can be created using `max_depth=None` and `min_samples_split=2`. However, these values are not necessarily optimal, especially for high-dimensional data with many samples and, consequently, potentially very deep trees that can become very computationally-, and memory-, intensive.\n",
    "\n",
    "The `RandomForest` class provided by sklearn support parallel training and prediction by setting the n_jobs parameter to the k number of jobs to run on different cores. The -1 value uses all available cores. The overhead of interprocess communication may limit the speedup from being linear so that k jobs may take more than 1/k the time of a single job. Nonetheless, the speedup is often quite significant for large forests or deep individual trees that may take a meaningful amount of time to train when the data is large, and split evaluation becomes costly.\n",
    "\n",
    "As always, the best parameter configuration should be identified using cross-validation. The following steps illustrate the process:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Define Parameter Grid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:02:34.206871Z",
     "start_time": "2020-06-19T14:02:34.194739Z"
    }
   },
   "outputs": [],
   "source": [
    "param_grid = {'n_estimators': [50, 100, 250],\n",
    "              'max_depth': [5, 15, None],\n",
    "              'min_samples_leaf': [5, 25, 100]}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Instantiate GridSearchCV"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will use 10-fold custom cross-validation and populate the parameter grid with values for the key configuration settings:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:02:34.216640Z",
     "start_time": "2020-06-19T14:02:34.208010Z"
    }
   },
   "outputs": [],
   "source": [
    "gridsearch_clf = GridSearchCV(estimator=rf_clf,\n",
    "                              param_grid=param_grid,\n",
    "                              scoring='roc_auc',\n",
    "                              n_jobs=-1,\n",
    "                              cv=cv,\n",
    "                              refit=True,\n",
    "                              return_train_score=True,\n",
    "                              verbose=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Fit Classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:08:56.463617Z",
     "start_time": "2020-06-19T14:03:01.883962Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 10 folds for each of 27 candidates, totalling 270 fits\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.\n",
      "[Parallel(n_jobs=-1)]: Done  34 tasks      | elapsed:   26.5s\n",
      "[Parallel(n_jobs=-1)]: Done 184 tasks      | elapsed:  3.5min\n",
      "[Parallel(n_jobs=-1)]: Done 270 out of 270 | elapsed:  5.8min finished\n",
      "[Parallel(n_jobs=-1)]: Using backend ThreadingBackend with 8 concurrent workers.\n",
      "[Parallel(n_jobs=-1)]: Done  34 tasks      | elapsed:    1.3s\n",
      "[Parallel(n_jobs=-1)]: Done 100 out of 100 | elapsed:    3.5s finished\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=<utils.MultipleTimeSeriesCV object at 0x7fc2d2f90050>,\n",
       "             estimator=RandomForestClassifier(n_jobs=-1, oob_score=True,\n",
       "                                              random_state=42, verbose=1),\n",
       "             n_jobs=-1,\n",
       "             param_grid={'max_depth': [5, 15, None],\n",
       "                         'min_samples_leaf': [5, 25, 100],\n",
       "                         'n_estimators': [50, 100, 250]},\n",
       "             return_train_score=True, scoring='roc_auc', verbose=1)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gridsearch_clf.fit(X=X, y=y_binary)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Persist Result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:11:07.626884Z",
     "start_time": "2020-06-19T14:11:07.566239Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['gridsearch_clf.joblib']"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "joblib.dump(gridsearch_clf, results_path / 'gridsearch_clf.joblib') "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:11:08.208357Z",
     "start_time": "2020-06-19T14:11:08.168542Z"
    }
   },
   "outputs": [],
   "source": [
    "gridsearch_clf = joblib.load(results_path / 'gridsearch_clf.joblib') "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:11:08.915250Z",
     "start_time": "2020-06-19T14:11:08.912597Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'max_depth': 15, 'min_samples_leaf': 5, 'n_estimators': 100}"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gridsearch_clf.best_params_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:11:09.069914Z",
     "start_time": "2020-06-19T14:11:09.066907Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5210305933900112"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gridsearch_clf.best_score_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Feature Importance"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A random forest ensemble may contain hundreds of individual trees, but it is still possible to obtain an overall summary measure of feature importance from bagged models.\n",
    "\n",
    "For a given feature, the importance score is the total reduction in the objective function's value, which results from splits based on this feature, averaged over all trees. Since the objective function takes into account how many features are affected by a split, this measure is implicitly a weighted average so that features used near the top of a tree will get higher scores due to the larger number of observations contained in the much smaller number of available nodes. By averaging over many trees grown in a randomized fashion, the feature importance estimate loses some variance and becomes more accurate.\n",
    "\n",
    "The computation differs for classification and regression trees based on the different objectives used to learn the decision rules and is measured in terms of the mean square error for regression trees and the Gini index or entropy for classification trees.\n",
    "\n",
    "`sklearn` further normalizes the feature-importance measure so that it sums up to 1. Feature importance thus computed is also used for feature selection as an alternative to the mutual information measures we saw in Chapter 6, The Machine Learning Process (see SelectFromModel in the sklearn.feature_selection module).\n",
    "In our example, the importance values for the top-20 features are as shown here:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:11:12.436760Z",
     "start_time": "2020-06-19T14:11:12.104126Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1gAAAFgCAYAAACmKdhBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nOzde1TVVf7/8dcHOIgIKl5KlFigpJKlllo2fjV1kSnWlBReskM2TY7TjJZGKo4WY+MtyVKcn7cglBpF81gZOjaildKENmXjWCpSXkADCk25HC6H8/ujhpWj4O3AB+T5WGvW8nzOZ+/9/nxaq+bl3mdvw+l0OgUAAAAAuGZuZhcAAAAAANcLAhYAAAAAuAgBCwAAAABchIAFAAAAAC5CwAIAAAAAFyFgAQAAAICLeJhdAADg+talSxd17txZbm5uMgxDJSUl8vHxUWxsrG677TZlZGToqaeeUnBw8HntRo8erTFjxpx3bfr06UpPT1erVq3Ou75y5UrdeOONV1Xfb37zG8XFxV3Qp6tMnz5dN998s5588sla6b86J06c0Msvv6z4+Pg6HRcAGjsCFgCg1q1evfq8AJOQkKC//OUvSklJkSQFBgbq3Xffvay+xo0b59Kwkp6e7rK+6pOTJ0/q22+/NbsMAGh0CFgAgDpVUVGhU6dOqUWLFi7tt6ysTHFxcdq7d68cDoduueUWzZw5Uz4+Ptq5c6dWrFihsrIyFRQU6KGHHtKzzz6rmJgYSdLjjz+ulStXauzYsVq8eLFuu+02SdLgwYO1ePFi+fn5aezYserUqZNycnKUnJys7OxsxcXFqaSkRG5ubvrjH/+oQYMG1Vij1WpVt27dtG/fPhUUFGjkyJH6/vvvtWfPHpWUlOi1115Tly5dZLVadcstt+hf//qXTp8+rQcffFCTJk2SJG3fvl1Lly5VZWWlmjVrppiYGHXv3l3x8fHat2+f8vLydPPNN2v//v3Kzc3Vk08+qYSEBC1fvlxpaWmy2+0qKSnRtGnTdO+99yo+Pl45OTnKz89XTk6ObrzxRi1cuFA33HCDvv32W73wwgsqKCiQm5ubfv/73ys8PFy5ubmaPXu2Tp06pfLycg0fPlwTJkxw6T9PAGioCFgAgFr3+OOPS5JOnz6tJk2aaNCgQZo3b17V98ePH9eDDz5Y9dnf31/Lly+/aF9JSUl67733qj4/9thjioyM1MqVK+Xu7i6bzSbDMLRo0SLFxcXpxRdfVGJioubPn6+goCDl5uZq0KBBioqK0rx582Sz2S6YYbuY7777Tq+88op69+6tH3/8UTExMUpISFBAQIByc3M1cuRIdenSRe3bt6+xn5ycHK1bt05ffvmlRo4cqWXLlmn69OmaO3eu3nzzTb300kuSpG+//VZr165VSUmJRo4cqdtuu02BgYF68cUXtW7dOt1000365z//qaefflp///vfq/p+//335eHhoYyMDL300ktKSEhQTk6OPvnkEyUnJ8vLy0upqalasmSJ7r33XknSZ599pnfeeUc+Pj6aMGGC1q1bp0mTJmnKlCl65JFHNHbsWJ06dUpWq1UDBgzQ888/r3Hjxmnw4MEqLS3VU089pcDAQIWHh9f47ADQGBCwAAC17r8B5sCBAxo/frzuuusutW7duup7VywR/PDDD3Xu3Dl98sknkqTy8nK1bt1ahmFo+fLl+vDDD/X+++8rKytLTqdTJSUlV/QMHh4e6tmzpyRp3759ys/P1x/+8Ieq7w3D0KFDhy4ZsP4bam666SZJUv/+/SX99A727NlTdd+oUaNksVhksVg0dOhQ7d69Wx07dlTfvn2r2t59991q1aqV/vOf/0iSevbsKQ+PC//T3qFDB7388svavHmzjh07pi+//FJFRUVV3995553y8fGRJN1yyy368ccfdebMGR08eFCRkZGSfgq927dvV3Fxsfbu3asff/xRixcvliQVFxfr4MGDBCwAEAELAFCHunXrppiYGE2fPl2hoaEKCAhwWd+VlZWaMWOG7rnnHklSUVGRSktLVVxcrBEjRigsLEy9e/fWww8/rO3bt8vpdF60n19eLysrq/qzp6dnVXhxOBzq1KmTNmzYUPV9bm7uZW2U4enped5ni8Vy0ft+GZScTqfc3NxUWVkpwzAuqLeiokKS5O3tfdG+Dhw4oKefflrjxo1Tv3791KdPH/35z3+u+t7Ly6vqz4ZhyOl0Vo3/y/G++eYbtW3bVk6nU+vWrVPTpk0lSQUFBWrSpMklnx0AGgO2aQcA1Kn7779f3bt3P2+JoCv83//9n9566y2VlZWpsrJSs2bN0qJFi3Ts2DEVFhbq2Wef1eDBg5WRkVF1jyS5u7tXBZRfzgZlZGQoPz//omP17NlTx44d0969eyVJX3/9te677z7l5ua67Hnee+89VVZW6scff9TWrVs1ePBg3X333dq9e7dOnDghSfrnP/+pU6dOqUePHhe0d3d3V3l5uSRp7969uvXWW/XEE0/ozjvvVFpamhwOR43j+/j4qFu3bnrnnXckSadOndKYMWNkt9vVs2dPvfHGG5Kks2fPasyYMUpLS3PZswNAQ8YMFgCgzs2aNUu//vWvtWvXrgtmdK7W008/rQULFmjEiBFyOBwKDQ3V9OnT5e3trYEDB2rYsGHy9PRU586dFRISomPHjikwMFBDhw6V1WpVfHy8oqOjFRsbq5SUFHXr1k3dunW76FitWrXSkiVL9PLLL6u0tFROp1Mvv/yyS2fk7Ha7HnnkERUVFenRRx/V3XffLUl68cUX9cc//lEOh0NeXl5avny5fH19L2gfEhKiJk2a6JFHHtHy5cv1wQcfaNiwYaqsrNSgQYP0448/qrCwsMYaXnnlFf35z39WcnKyDMPQnDlz1LZtW8XFxemll17SAw88oLKyMt1///369a9/7bJnB4CGzHBWt0YCAACYwmq1auzYsRo6dKjZpQAArhBLBAEAAADARZjBAgAAAAAXYQYLAAAAAFyEgAUAAAAALkLAMsHFDsgEAAAA0PARsExw+vRps0sAAAAAUAsIWAAAAADgIgQsAAAAAHARApYJ2BgfAAAAuDL2cofZJVwWD7MLaIgOHTqks2fPqk+fPho8eLC2bt2qJk2aXHZ7w5CCpqfWYoUAAADA9eXo/OFml3BZmMG6Ch988IGOHDlidhkAAAAA6plGM4Nls9m0c+dO2e125efnKyoqSmlpacrMzNTUqVNVXFys1atXy9PTU0FBQZo9e7Y2b96sjz76SHa7XcePH9dTTz2lfv36adOmTbJYLOrWrZskKTY2VtnZ2ZKkpUuXqkWLFmY+KgAAAACTNJqAJUlFRUVKTExUamqqkpKStH79emVkZCgpKUlZWVnatGmTfHx8NHfuXKWkpMjb21uFhYVKSEjQ0aNHNWHCBEVERGjEiBFq06aNunfvLkl6+OGH1bt3b02fPl3p6ekKDw83+UkBAAAAmKFRLREMDQ2VJPn6+qpTp04yDEMtWrRQSUmJQkJC5OPjI0nq06ePMjMzJUldu3aVJPn7+6usrOyi/d56662SpDZt2shut9f2YwAAAACopxpVwDIMo9rrWVlZKi4uliTt2bNHwcHB1bYxDEOVlZWX7BcAAABA49KoAlZ13N3dNXHiREVFRWnkyJE6ffq0xowZU+39t956q9566y19+umndVglAAAAgPrOcDo5lamujRgRoU2bbGaXAQAAADQY9nKHvCzuZpdxScxgmYAVhQAAAMCVaQjhSiJgAQAAAIDLELAAAAAAwEUIWAAAAADgIgQsAAAAAHARAhYAAAAAuAgBCwAAAABchIBlAk4eAwAAV8Ne7jC7BACX4GF2AY2RYUhB01PNLgMAADQwR+cPN7sEAJfADBYAAAAAuAgzWD977rnn9MADD2jgwIHKysrSggUL1KZNGx07dkyVlZV69tlnddddd+nvf/+73nrrrap2ixcvVmZmpuLi4mSxWDRy5Eg99NBDJj4JAAAAALMQsH4WGRmptWvXauDAgXr77bd1++23q7CwUHPnztXp06f12GOPKTU1VUePHtXKlSvVtGlTvfDCC9q9e7duvPFGlZaWasOGDWY/BgAAAAATEbB+dtddd2nOnDn64YcflJ6erttvv12ff/65/v3vf0uSKioqdPr0abVu3VrTpk1Ts2bN9M0336hnz56SpODgYDPLBwAAAFAPELB+ZhiGHnjgAc2ZM0f9+vWTv7+//P39NWHCBNntdi1btkweHh5asmSJPvzwQ0nSE088IefPWwK6ufFzNgAAAKCxI2D9QkREhAYOHKh3331XN910k2bOnKnHHntMhYWFevTRR+Xj46M77rhDI0aMkLe3t5o3b668vDwFBARc0ThOJ7sAAQCAK2cvd8jL4m52GQBqQMD6BYfDoV69eqlTp06SpJdffvmCexYvXnzRtnfddddlj2MYV1cfAABo3AhXQP3Hurafbdu2Tb/97W/13HPPmV0KAAAAgAaKGayf3XfffbrvvvvMLgMAAABAA8YMFgAAAAC4CAELAAAAAFyEgAUAAAAALkLAAgAAAAAXIWCZ4OeziQEA9ZS93GF2CQCABopdBK9RSkqKIiIiZLFYLruNYUhB01NrsSoAwLXgMHgAwNViBusarVixQpWVlWaXAQAAAKAeYAbrImw2mz766CPZ7XYdP35cTz31lAICArR06VJJkt1u14IFC/TZZ58pPz9fkydP1uOPP664uDhZLBaNHDlSDz30kMlPAQAAAKCuMYNVjcLCQq1YsULLli3TypUrlZmZqYUL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\n",
      "text/plain": [
       "<Figure size 864x360 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(12,5))\n",
    "(pd.Series(gridsearch_clf.best_estimator_.feature_importances_, \n",
    "           index=X.columns)\n",
    " .sort_values(ascending=False)\n",
    " .iloc[:20]\n",
    " .sort_values()\n",
    " .plot.barh(ax=ax, title='RF Feature Importance'))\n",
    "sns.despine()\n",
    "fig.tight_layout();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Fit Regressor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:11:18.445851Z",
     "start_time": "2020-06-19T14:11:18.443063Z"
    }
   },
   "outputs": [],
   "source": [
    "gridsearch_reg = GridSearchCV(estimator=rf_reg,\n",
    "                      param_grid=param_grid,\n",
    "                      scoring=ic,\n",
    "                      n_jobs=-1,\n",
    "                      cv=cv,\n",
    "                      refit=True,\n",
    "                      return_train_score=True,\n",
    "                      verbose=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:11:18.593401Z",
     "start_time": "2020-06-19T14:11:18.591255Z"
    }
   },
   "outputs": [],
   "source": [
    "gs_reg = gridsearch_reg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:39:12.336257Z",
     "start_time": "2020-06-19T14:11:18.694915Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 10 folds for each of 27 candidates, totalling 270 fits\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.\n",
      "[Parallel(n_jobs=-1)]: Done  34 tasks      | elapsed:  1.9min\n",
      "[Parallel(n_jobs=-1)]: Done 184 tasks      | elapsed: 16.4min\n",
      "[Parallel(n_jobs=-1)]: Done 270 out of 270 | elapsed: 27.8min finished\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=<utils.MultipleTimeSeriesCV object at 0x7fc2d2f90050>,\n",
       "             estimator=RandomForestRegressor(n_jobs=-1), n_jobs=-1,\n",
       "             param_grid={'max_depth': [5, 15, None],\n",
       "                         'min_samples_leaf': [5, 25, 100],\n",
       "                         'n_estimators': [50, 100, 250]},\n",
       "             return_train_score=True, scoring=make_scorer(rank_correl),\n",
       "             verbose=1)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gridsearch_reg.fit(X=X, y=y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:39:12.367059Z",
     "start_time": "2020-06-19T14:39:12.337291Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['rf_reg_gridsearch.joblib']"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "joblib.dump(gridsearch_reg, results_path / 'rf_reg_gridsearch.joblib') "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:39:12.388885Z",
     "start_time": "2020-06-19T14:39:12.368589Z"
    }
   },
   "outputs": [],
   "source": [
    "gridsearch_reg = joblib.load(results_path / 'rf_reg_gridsearch.joblib') "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:39:12.392811Z",
     "start_time": "2020-06-19T14:39:12.390276Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'max_depth': 5, 'min_samples_leaf': 5, 'n_estimators': 50}"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gridsearch_reg.best_params_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:39:12.404720Z",
     "start_time": "2020-06-19T14:39:12.393971Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'4.93'"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f'{gridsearch_reg.best_score_*100:.2f}'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Compare Results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Best Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:39:12.417841Z",
     "start_time": "2020-06-19T14:39:12.405926Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Regression</th>\n",
       "      <th>Classification</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>max_depth</th>\n",
       "      <td>5</td>\n",
       "      <td>15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min_samples_leaf</th>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>n_estimators</th>\n",
       "      <td>50</td>\n",
       "      <td>100</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                  Regression  Classification\n",
       "max_depth                  5              15\n",
       "min_samples_leaf           5               5\n",
       "n_estimators              50             100"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.DataFrame({'Regression': pd.Series(gridsearch_reg.best_params_),\n",
    "              'Classification': pd.Series(gridsearch_clf.best_params_)})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Feature Importance"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:39:12.629807Z",
     "start_time": "2020-06-19T14:39:12.418658Z"
    }
   },
   "outputs": [],
   "source": [
    "fi_clf = gridsearch_clf.best_estimator_.feature_importances_\n",
    "fi_reg = gridsearch_reg.best_estimator_.feature_importances_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:39:12.633012Z",
     "start_time": "2020-06-19T14:39:12.631031Z"
    }
   },
   "outputs": [],
   "source": [
    "idx = [c.replace('_', ' ').upper() for c in X.columns]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-19T14:39:13.031821Z",
     "start_time": "2020-06-19T14:39:12.633997Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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kpLCiBEjAHBzc2P48OEkJSUZ347n5OTw7rvvEhERUa5/UFAQYWFhJCcn13nsIiIijZ3yuIiINCYN/g46QEhICO+//z5+fn7k5OQAMHXqVBYvXszo0aNxc3PDbDYzZ84cfH19yc3NLdd/0qRJ7Nmzp9biczj0+h0RkYausNiOu5trfYdxU1IeFxERZ1AXudzkcDgctTqCXFNERAQbN26s7zBERETkOiiPi4hITWnwS9xFREREREREbgYq0EVEREREREScgAp0ERERERERESegAl1ERERERETECahAFxEREREREXECKtBFREREREREnIAKdCegF92JSG0qLLbXdwgiDZryuIjUBuXvxqlJfQdQ3/7f//t/dOnShaeeegoAm81GREQEgYGB/PTTT3h7exttR4wYwahRowD46quvePjhh3n33Xfp2rUrABs3bmTRokX4+voCcP78ebp168bLL79caQwmE9xm3V4bpyciwpH40PoOQaTWKI+LSEOl/N04NfoCPTY2lpEjRzJo0CACAwNJSEjgoYce4vvvv+f555+nf//+V+y3bt06Hn/88XKJHSAsLIypU6cCUFpaSmRkJP/85z+566676uR8REREGhPlcRERaUga/RJ3Hx8fXnrpJWbMmMHnn39OTk4Ojz/+eKV9bDYbGRkZPPPMMxw4cIAzZ85ctd0vv/xC8+bNayN0ERGRRk95XEREGpJGfwcdYNCgQXzwwQdYrVZSU1MxmUwAJCYmkpycbLSbMWMGd955Jzt27GDIkCE0bdqU4cOHs379emNp3bZt2/jyyy85efIkHh4eTJo0idtuu60+TktERKRRUB4XEZGGQgX6v91///0UFhbSpk0bY9vVlsatW7cOV1dXnnjiCQoLC/n555+ZMGEC8H9L43JycpgwYYKSuoiISB1QHhcRkYZABXo1HTp0CLvdznvvvWdse/zxx9mzZ0+5dr6+vrz88sv8+c9/Zvv27TRr1qyuQxUREZHfUB4XERFnpgK9Er9dGvdf//VfnD9/nj/96U/l2o0aNYrVq1cTFhZWbnvv3r3p3bs3ixYtIiYmpk5iFhERkUuUx0VE5GZjcjj09s769sADEWzatLG+wxCRBqqw2I67m2t9hyHSYCmPi0htUP5unBr9U9ydwb+fZSMiUiuU3EVql/K4iNQG5e/GSQW6iIiIiIiIiBNQgS4iIiIi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R48exc3Njd///vfccccd3HfffURFRREYGAiAzWajQ4cOLFiwALPZXOnxTSa4zbr9mnEciQ+tkfMRERFp6DIzM1mzZg1JSUnGtgULFuDv78+0adOIjo7mqaeeMvZNmjQJm81GSkoKFouF2NhYAgICqjRWVfO4yPXSHFCk8VCBXgVbt24lJCSE7du388orrwCwePFiWrVqxdixY4FLE4GePXuWmwhER0eze/duhg0bVi9xi4iISEUdO3Zk165dRoF+9uxZsrOzadWqVT1HJiIijZ2WuF9DZmYmHTt2ZMyYMaxevbrK/YqKisjLy8PLy6sWoxMREZHqatGiBS1btuTw4cMA7NixQ1+mi4iIU1CBfg3r1q1j1KhR+Pv7Yzab+eqrr67aNiMjA4vFQkhICBEREQwZMoRevXrVYbQiIiJSpiwvl/3Ztm2bsS80NJTt2y8tS09LSyM4OLi+whQRETFoiXslzp07R3p6OmfOnCElJYVff/2VVatWcffdd1+xfdkS9/z8fMaPH0+HDh3qOGIREREp89ufni1YsMD4e3BwMA8//DARERG0bt0ad3f3+ghRRESkHBXoldiyZQsjR44kJiYGgAsXLjB48GDOnDlTab8WLVqQmJjIuHHj2Lx5M7///e/rIlwRERGpIg8PD/z8/EhMTGTUqFH1HY6IiAigJe6VWrduHX/605+Mz82aNeO+++7jvffeu2bfwMBALBYLc+bMqc0QRURE5DqFh4fzv//7v1f8Odqf//xnIiIiiIiIICEhoR6iExGRxsjkcOjtnfXtgQci2LRp4zXbFRbbcXdzrYOIREREpKqqmsf/f3t3HxxVfe9x/L15WEITmgThAiWLEFKkDaVXpCIgeJEnCSTIogGDm9oogni1QFITNXLjkEpomGZqrlRluBWCUiyEhwLCRcChEpPeOFKmcEvFFEwiJRiDTB5INtlz/+Byhm0eCFuSHMznNeMM5/H3Pd+J+/t9z/ntWRFfaQwo0n3oCboF2Gzt208fzCIiItbT3n5cxFcaA4p0HyrQRURERERERCxABbqIiIiIiIiIBahAFxEREREREbEAFegiIiIiIiIiFqACXURERERERMQCVKCLiIiIiIiIWIAKdAto65foL7ubOi8QERERuWFt9eMiN4PGgyLdR0BXNl5UVMTSpUuJiooCoKamhoiICNasWUNFRQVxcXFE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\n",
      "text/plain": [
       "<Figure size 1008x288 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = plt.subplots(figsize=(14, 4), ncols=2)\n",
    "(pd.Series(fi_clf, index=idx)\n",
    " .sort_values(ascending=False)\n",
    " .iloc[:15]\n",
    " .sort_values()\n",
    " .plot.barh(ax=axes[1], title='Classifier'))\n",
    "(pd.Series(fi_reg, index=idx)\n",
    " .sort_values(ascending=False)\n",
    " .iloc[:15]\n",
    " .sort_values()\n",
    " .plot.barh(ax=axes[0], title='Regression'))\n",
    "sns.despine()\n",
    "fig.tight_layout()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": true,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "281.225px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
